#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>

static int g_fd;
void signal_handler(int signo)
{
    printf("Receive signal[%d]\n", signo);
    if(signo == SIGIO)
    {
        unsigned char key_val;
        read(g_fd, &key_val, 1);
        if(key_val & 0x80) //松开
            printf("The key[%u] is released\n", key_val & 0x0f);
        else    //按下
            printf("The key[%u] is pressed\n", key_val & 0x0f);
    }
}

int main(int argc,char *argv[])
{
    const char *dev_name = "/dev/key";
	g_fd = open(dev_name, O_RDWR);
    if(g_fd < 0)
        printf("Open the device:[%s] failed\n", dev_name);

    //[0]. 注册一个信号处理函数
    signal(SIGIO, signal_handler);
    //[1]. 为了使内核驱动发送的信号能够到达本应用程序，需要将本程序的进程ID告诉内核
    pid_t pid = getpid();
    fcntl(g_fd, F_SETOWN, pid);
    //[2]. 修改文件描述符g_fd的flag,使其可以接收异步信号
    int old_flags = fcntl(g_fd, F_GETFL);
    int new_flags = old_flags | FASYNC;
    fcntl(g_fd, F_SETFL, new_flags);
    
    while(1)
    {
        sleep(100);
    }
	close(g_fd);
	return 0;
}
